package com.zhj.common.db.mysql.plugins;

import com.zhj.common.db.mysql.util.MybatisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Statement;

/**
 * 打印SQL语句
 * 1. 记录SQL语句
 * 2. 记录执行的时间
 * type 增强的内置对象的类型（必须是四大内置对象中的一个 StatementHandler.class(增强最多的)）
 * method 增强的方法名
 * args{} 是形参列表，防止方法重载，找不到对应的方法
 * @author zhj
 */
@Slf4j
@Intercepts({
        @Signature(
                type = StatementHandler.class,
                method = "query",
                args = {Statement.class, ResultHandler.class}
        ),
        @Signature(
                type = StatementHandler.class,
                method = "update",
                args = {Statement.class}
        )
})
public class PrintSQLPlugins implements Interceptor {

    /**
     * 拦截方法
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取非代理对象
        StatementHandler target = MybatisUtils.getNoProxyTarget(invocation.getTarget());
        BoundSql boundSql = target.getBoundSql();
        String sql = boundSql.getSql();
        log.info("[SQL]-------------------------------");
        log.info(sql.replace("\n",""));
        long beginTime = System.currentTimeMillis();
        Object proceed = invocation.proceed(); // 放行，执行目标对象的对应方法
        long endTime = System.currentTimeMillis();
        log.info("[SQL执行的时长为：{} s]", BigDecimal.valueOf(endTime - beginTime).divide(BigDecimal.valueOf(1000)).setScale(6, RoundingMode.DOWN).doubleValue());
        return proceed;
    }
}
